package linc.fun.openai.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.Lists;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import linc.fun.openai.constants.RedisKeyConstants;
import linc.fun.openai.domain.entity.chat.ChatProductDO;
import linc.fun.openai.domain.vo.ChatTop4ProductsVO;
import linc.fun.openai.enums.EnableDisableStatusEnum;
import linc.fun.openai.exception.BizException;
import linc.fun.openai.mapper.ChatProductMapper;
import linc.fun.openai.service.ChatProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static linc.fun.openai.domain.entity.chat.table.Tables.ChatProduct;

/**
 * @author yqlin
 * @date 2023/5/8 00:01
 * @description
 */
@Service
@Slf4j
public class ChatProductServiceImpl extends ServiceImpl<ChatProductMapper, ChatProductDO> implements ChatProductService {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public ChatTop4ProductsVO getTop4Products() {
        Map<Object, Object> cachedProductStockMap = redisTemplate.opsForHash()
                .entries(RedisKeyConstants.CHAT_PRODUCT_ID_STOCK_KEY);
        if (CollUtil.isEmpty(cachedProductStockMap)) {
            log.info("商品库存明细数据丢失");
            throw BizException.DATA_HAS_BEEN_LOOSED;
        }
        List<Long> cachedProductIds = cachedProductStockMap.keySet().stream().map(productId -> Long.valueOf((String) productId)).collect(Collectors.toList());
        List<ChatProductDO> cachedProducts = this.queryChatProductsByIds(cachedProductIds);
        List<ChatProductDO> chatProducts = Lists.newArrayList();
        for (ChatProductDO cachedProduct : cachedProducts) {
            Integer currentStock = (Integer) cachedProductStockMap.get(cachedProduct.getId().toString());
            ChatProductDO productDO = new ChatProductDO();
            productDO.setId(cachedProduct.getId());
            productDO.setName(cachedProduct.getName());
            productDO.setPrice(cachedProduct.getPrice());
            productDO.setSale(cachedProduct.getSale());
            productDO.setRewardUseTimes(cachedProduct.getRewardUseTimes());
            productDO.setStock(currentStock);
            chatProducts.add(productDO);
        }
        return new ChatTop4ProductsVO(chatProducts.stream()
                .sorted(Comparator.comparing(ChatProductDO::getStock).reversed())
                .limit(4)
                .collect(Collectors.toList()));
    }

    private List<ChatProductDO> queryChatProductsByIds(List<Long> productIds) {
        QueryWrapper cWrapper = QueryWrapper.create()
                .where(ChatProduct.Id.in(productIds))
                .and(ChatProduct.Status.eq(EnableDisableStatusEnum.ENABLE));
        return this.list(cWrapper);
    }
}
